#ifndef KMSFILESYSTEMWATCHER_H
#define KMSFILESYSTEMWATCHER_H

#include <QObject>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <QCryptographicHash>
#include <QFileInfo>
#include <QDir>
#include <QThread>
#include <QMutex>
#include <QHash>
#include <QList>
#include <uv.h>
#include "database/database_manager.h"

// 前向声明用于存储监听器信息
struct WatcherInfo;

// 事件类型枚举
enum class FsEventType {
    FileAdded,        // 文件新增
    FileModified,     // 文件内容变更
    FileOrDirDeleted,       // 文件或目录删除
    DirAdded,         // 目录新增
};

// 文件系统动作结构
struct FsAction {
    FsEventType eventType;
    QString *path;
};

class KmsFileSystemWatcher : public QObject
{
    Q_OBJECT

public:
    explicit KmsFileSystemWatcher(QObject *parent = nullptr);
    ~KmsFileSystemWatcher();

    // 设置数据库管理器
    void setDatabaseManager(DatabaseManager *dbManager);

    // 开始监听指定目录
    void startWatching(const QString &directoryPath);

    // 停止监听
    void stopWatching();

    // 获取当前监听的目录
    QString getWatchedDirectory() const;

    // 检查文件是否在监听目录中
    bool isFileInWatchedDirectory(const QString &filePath) const;

signals:

    // 文件数据变化（状态/校验和变化）
    void filesChanged();

private slots:
    // 处理文件事件（从 libuv 线程调用，内部使用）
    void handleFileOrDirDeletedEvent(const QString &filePath);
    void handleFileAddedOrChangedEvent(const QString &path);
    void handleDirAddedEvent(const QString &path);

    // 延迟处理文件变更（避免频繁更新）
    void processDelayedFsActions();
    
    // 启动延迟处理定时器（从 libuv 线程调用，内部使用）
    void startDelayTimer();

private:
    // libuv 相关
    uv_loop_t *m_loop;
    QThread *m_eventLoopThread;
    QMutex m_watchersMutex;
    QHash<QString, WatcherInfo*> m_watchers; // 路径 -> 监听器信息
    
    DatabaseManager *m_databaseManager;
    QString m_watchedDirectory;
    QMutex m_pendingActionsMutex;  // 保护 m_pendingActions 的互斥锁
    QList<FsAction> m_pendingActions;
    QTimer *m_delayTimer;
    
    bool m_stopping;

    // 计算文件校验和
    QString calculateFileChecksum(const QString &filePath);

    // 更新数据库中的文件信息
    void updateFileInfoInDatabase(const QString &filePath);

    // 获取文件相对于监听目录的路径
    QString getRelativeFilePath(const QString &filePath) const;

    // 根据相对路径查找对应的文件ID
    QString findFileIdByRelativePath(const QString &relativePath) const;
    
    // 根据本地文件路径（相对路径）查找对应的文件ID
    QString findFileIdByLocalFilePath(const QString &relativePath) const;
    
    // libuv 相关方法
    void startEventLoop();
    void stopEventLoop();
    bool addWatcher(const QString &path, bool isDirectory);
    void removeWatcher(const QString &path);
    void removeAllWatchers();
    
    // libuv 回调函数（静态）
    static void onFsEvent(uv_fs_event_t *handle, const char *filename, int events, int status);
    
    // 事件循环线程入口
    void runEventLoop();
};

#endif // KMSFILESYSTEMWATCHER_H
